const { ccclass, property } = cc._decorator;
/** 
 * 倒计时组件
 * 使用说明：
 *
// 一个10秒的倒计时，每1秒执行一次回调，倒计时的关键字是timer1
FYCountDownMgr.Instance.add("timer1", 10, 1, function (bFinish, curTime) {
    if (bFinish) {
        console.log("时间到 " + curTime);
    } else {
        console.log("当前时间 " + curTime);
    }

});  

 */
@ccclass
export default class FYCountDownMgr extends cc.Component {
    private static _instance: FYCountDownMgr = null;
    public static get Instance() {
        if (FYCountDownMgr._instance === null) {
            // 先去获取
            FYCountDownMgr._instance = cc.director.getScene().getChildByName("Canvas").getComponent(FYCountDownMgr);
        }
        if (FYCountDownMgr._instance === null) {
            // 获取不到则添加
            FYCountDownMgr._instance = cc.director.getScene().getChildByName("Canvas").addComponent(FYCountDownMgr);
        }
        return FYCountDownMgr._instance;
    }
    /** 是否开始倒计时 */
    private _bStart = false;
    /** 倒计时信息字典 */
    private _dictCountDownInfo = {};


    /**
     * 
     * @param key 关键字
     * @param startTime 起始时间
     * @param needTime 需要时间 倒计时一共执行多久 -1: 一直执行
     * @param intervalTime 间隔时间 多久执行一次回调 -1: 直到结束 中间都不执行回调
     * @param callback 回调函数
     */
    public add(key: string, startTime: number, needTime: number, intervalTime: number, callback: Function) {
        if (this._dictCountDownInfo[key]) {
            cc.warn("key = " + key + "is already exist");
            // delete this._dictCountDownInfo[key];
        }

        let countDownInfo = new CountDownInfo(key, startTime, needTime, intervalTime, callback);
        this._dictCountDownInfo[key] = countDownInfo;

        this._bStart = true;
    }


    public remove(key: string) {
        if (this._dictCountDownInfo[key]) {
            delete this._dictCountDownInfo[key];
        }
    }

    // ------------------------------- 回调函数 -------------------------------------- //



    // ------------------------------- 生命周期 -------------------------------------- //

    update(dt) {
        if (!this._bStart) {
            return;
        }

        for (let key in this._dictCountDownInfo) {
            let countDownInfo: CountDownInfo = this._dictCountDownInfo[key];
            countDownInfo.curTime += dt;
            if (countDownInfo.intervalTime != -1) {
                countDownInfo.intervalTotalTime += dt;
            }
            if (countDownInfo.needTime != -1 && countDownInfo.curTime >= countDownInfo.needTime) {
                delete this._dictCountDownInfo[key];

                if (Object.keys(this._dictCountDownInfo).length === 0) {
                    // 倒计时停止
                    this._bStart = false;
                }

                if (countDownInfo.cb) {
                    countDownInfo.cb(true, countDownInfo.curTime);
                }
            } else if (countDownInfo.intervalTime != -1 && countDownInfo.intervalTotalTime >= countDownInfo.intervalTime) {
                if (countDownInfo.cb) {
                    // 到达指定间隔时间 则执行回调 并返回当前累计时间
                    countDownInfo.cb(false, countDownInfo.curTime);
                }
                countDownInfo.intervalTotalTime = 0;
            }
        }
    }

}

/** 倒计时信息 */
class CountDownInfo {
    public key: string = "";
    /** 起始时间 */
    public startTime: number = 0;
    /** 需要的时间 -1 永不停止 */
    public needTime: number = 0;
    /** 间隔时间 多久执行一次回调 -1:直到时间到 中间不执行回调 */
    public intervalTime: number = 0;
    /** 累计间隔施加 */
    public intervalTotalTime: number = 0;
    /** 当前时间 */
    public curTime: number = 0;
    /** 回调函数 */
    public cb: Function = null;

    public constructor(key: string, startTime: number, needTime: number, intervalTime: number, cb: Function) {
        this.key = key;
        this.startTime = startTime;
        this.needTime = needTime;
        this.intervalTime = intervalTime;
        this.cb = cb;
        this.curTime = startTime;
        this.intervalTotalTime = 0;
    }
}
